package fserv.control;

import java.io.File;
import java.net.InetAddress;
import fserv.entities.Command;
import fserv.entities.FileProposition;
import fserv.entities.Reply;
import fserv.ni.CtrlToNI;
import fserv.ni.NIToCtrl;

/**
 * Main controller of the Chat System.
 * 
 * Handles all the logic of the Chat System.
 * Implements the State Design Pattern.
 * 
 * @author Arthur Bit-Monnot <abit@etud.insa-toulouse.fr>
 * @author Julien Marchand <jmarchan@etud.insa-toulouse.fr>
 */
public final class ClientController implements NIToCtrl, UserToCtrl, FileshareToCtrl {

    /**
     * Unique instance of the Controller (Singleton Pattern).
     */
    private static ClientController instance;
    
    /**
     * Reference to the Network Interface.
     */
    protected CtrlToNI ni;
    
    /**
     * Reference to the User Interface.
     */
    protected CtrlToUser ui;
    
    /**
     * Thread in which the Network Interface is running.
     */
    protected Thread niThread;
    
    /**
     * Constructor for the Controller.
     */
    private ClientController() {
    }

    /**
     * Returns the unique Controller instance (Singleton Pattern)
     * 
     * @return the Controller instance
     */
    public static ClientController getInstance() {
        if (instance == null) {
            instance = new ClientController();
        }
        return instance;
    }

    /**
     * Sets up the association between the Controller and the Network Interface.
     * 
     * @param ni the Network Interface. Must implement the CtrlToNI interface.
     */
    public void setNI(CtrlToNI ni) {
        this.ni = ni;
    }

    /**
     * Sets up the association between the Controller and the GUI.
     * 
     * @param ui the GUI. Must implement the CtrlToUser interface.
     */
    public void setUI(CtrlToUser ui) {
        this.ui = ui;
    }


    /*
     * All the following methods are documented in their respective interfaces.
     */
    
    /*
     * NIToCtrl implementation
     */
	@Override
    public void replyReceived(Reply rep) {
		ui.replyReceived(rep);
    }

	@Override
    public void commandReceived(Command cm) {
		throw new UnsupportedOperationException("Client doesn't receive commands");
    }

	@Override
    public void filePropositionReceived(FileProposition fp) {
//        state.filePropositionReceived(fp);
    }

    /*
     * UserToCtrl implementation
     */
	@Override
    public void sendCommand(String cmd) {
	    this.ni.send(new Command(cmd));
    }

	@Override
    public void sendFile(File file) {
		throw new UnsupportedOperationException("Not implemented yet");
    }

    /*
     * FileshareToCtrl implementation
     */
	@Override
    public void fileShareStarted(File file) {
		throw new UnsupportedOperationException("Not implemented yet");
    }
    
	@Override
    public void fileShareStopped(File file) {
		throw new UnsupportedOperationException("Not implemented yet");
    }
    
	@Override
    public void fileShareUploadStarted(File file, InetAddress addr) {
		throw new UnsupportedOperationException("Not implemented yet");
    }
    
  @Override
    public void fileShareUploadFinished(File file, InetAddress addr) {
		throw new UnsupportedOperationException("Not implemented yet");
    }
    
  @Override
    public void fileShareUploadFailed(File file, InetAddress addr) {
		throw new UnsupportedOperationException("Not implemented yet");
    }
    
  @Override
    public void fileShareDownloadStarted(File file, InetAddress addr) {
		throw new UnsupportedOperationException("Not implemented yet");
    }
    
  @Override
    public void fileShareDownloadFinished(File file, InetAddress addr) {
		throw new UnsupportedOperationException("Not implemented yet");
    }
    
  @Override
    public void fileShareDownloadFailed(File file, InetAddress addr) {
		throw new UnsupportedOperationException("Not implemented yet");
    }

	public void launchNI() {
		this.niThread = new Thread(this.ni);
		this.niThread.start();
	}

  @Override
  public void quit() {
    this.ni.stop(niThread);
  }
    
}